/*
 * device.h
 *
 *  Created on: Dec 8, 2010
 *      Author: fify
 */

#ifndef DEVICE_H_
#define DEVICE_H_

#include <sys/types.h>
#include <string>
#include <vector>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <map>
#include <sstream>

using std::string;
using std::vector;
using std::istringstream;
using std::pair;

namespace CncrVDevice
{

// Command type of all devices.
enum CmdType {
	CMD_ROUTE,
	CMD_ARP,
	CMD_INTERFACE	// Command used to configure the interface.
};

// Device types.
enum DeviceType {
	DEV_HOST,	// Host type
	DEV_ROUTER,	// Router type
	DEV_SWITCH	// Switch type
};

// Interface types.
enum ItfType {
	ITF_ETHER,	// Ethernet interface type
	ITF_SERIAL	// Serial interface type
};

struct ip_addr_t {
	struct in_addr ip;
	unsigned int mask;
};

class VRouter;
class VDeviceBase;

// The virtual interface class, all interface class should be derived from this.
class VItf
{
public:
	ItfType	m_type;	// The type of the interface, which is defined in ItfType
	string m_name;	// The name of the interface, which may vary in different devices

	VDeviceBase *m_device;	// Which device does this interface belong to.
	unsigned m_index;		// Interface number within the device.

public:
	VItf() {}
	virtual ~VItf() {}

protected:
	int m_id;		// For later usage.

public:
	VItf(string name, VDeviceBase *device)
	{
		static int no = 0;
		m_id = no ++;
		m_name = name;
		m_device = device;
	}
};

// The Ethernet interface derived from VItf.
class VEtherItf : public VItf
{
public:
	string m_mac;
	// IP address and its mask makes up a pair.
	vector<ip_addr_t> m_ip;

public:
	VEtherItf(string name, VDeviceBase *device) : VItf(name, device)
	{
		m_type = ITF_ETHER;
	}
	virtual ~VEtherItf() {}
};

// Commands for all device available.
class VCmd
{
public:
	CmdType m_type;


	VCmd() {}
	virtual ~VCmd() {}
};

// The route command for VRouter.
class VCmdRoute : public VCmd
{
public:
	friend class VRouter;

	ip_addr_t m_dest;
	ip_addr_t m_next_hop;

public:
	VCmdRoute();
	virtual ~VCmdRoute() {}
};

class VCmdInterface : public VCmd
{
public:
	vector<ip_addr_t> m_addrs;
	VItf *m_itf;

public:
	VCmdInterface(VItf *itf);
	virtual ~VCmdInterface() {}
};

// Device Base class, devices like Router, Switch will be derived from this.
class VDeviceBase
{
public:
	DeviceType m_type;				// The device type defined in DeviceType.

protected:
	vector <VCmd *> m_cmds;			// Configuration commands for the device.

	/*
	 * WARNING!!
	 * Q: qemu里边的每一个网卡是否有对应的名称？第一块网卡是否一定是em0？
	 * A: 跟系统的release版本有关
	 */
	vector <VItf *> m_itfs;			// Interfaces installed in the device.

private:
	unsigned short m_hardware;
	unsigned short m_software;

public:
	VDeviceBase(){}
	virtual ~VDeviceBase() {}
	virtual int add_cmd(string &line) { return 0; }			// For command parsing.
	unsigned short get_hardware() { return m_hardware; }
	unsigned short get_software() { return m_software; }
};

// Device derived from this: router, switch, host
class VRouter: public VDeviceBase
{
public:
	VRouter();
	virtual ~VRouter() {}

	// How many commands are there in the device.
	u_int32_t cmd_count();

	// Add command or interface to the device.
	int add_cmds(string &cmds);
	int remove_cmd(int pos);

	// Generate a device (router, e.g) command for specified devices (Juniper e.g).
	virtual void gererate_code(int pos, string &code) {}

	/*
	 * 从路由器中提取接口信息：对应MAC对应的接口的名称。
	 * 注：引入该函数已经打破了VRouter和其他模块松耦合的现状，我们不得不传入一个void *config，用来
	 * 连接路由器，以便从路由器上获取必要的信息。
	 * 例如：在VJRouter中，config为JConfig数据结构，用来连接并控制Juniper交换机。
	 */
	virtual int add_interface_ex(string &cmds, void *config) { return 0; }
	int add_interface(istringstream &iss);

private:
	int add_route_cmd(istringstream &iss);

	int add_cmd(string &line);
};

} // End of namespace.

#endif /* DEVICE_H_ */
